//
//  ArrayExtension.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/4.
//

import UIKit

extension Array {
    /// 模型数组去重
    func wn_handleFilter<E: Equatable>(_ filterCall: (Element) -> E) -> [Element] {
        var temp = [Element]()
        for model in self {
            let identifer = filterCall(model)
            if !temp.map( { filterCall($0) } ).contains(identifer) {
                temp.append(model)
            }
        }
        return temp
    }
    
    /// 是否包含
    func wn_contains<T>(obj: T) -> Bool where T : Equatable {
        return self.filter({$0 as? T == obj}).count > 0
    }
    
    mutating func removeAt(indexes: [Int]) {
        for i in indexes.sorted(by: >) {
            self.remove(at: i)
        }
    }
}

extension Array where Element : Equatable {

    // MARK: 3.1、刪除数组的中的元素(可刪除第一个出现的或者刪除全部出现的)
    /// 刪除数组的中的元素(可刪除第一个出现的或者刪除全部出现的)
    /// - Parameters:
    ///   - element: 要刪除的元素
    ///   - isRepeat: 是否刪除重复的元素
    @discardableResult
    mutating func wn_remove(_ element: Element, isRepeat: Bool = false) -> Array {
        var removeIndexs: [Int] = []
    
        for i in 0 ..< count {
            if self[i] == element {
                removeIndexs.append(i)
                if !isRepeat { break }
            }
        }
        // 倒序刪除
        for index in removeIndexs.reversed() {
            self.remove(at: index)
        }
        return self
    }

    // MARK: 3.2、从刪除数组中刪除一个数组中出现的元素，支持是否重复刪除, 否则只刪除第一次出现的元素
    /// 从刪除数组中刪除一个数组中出现的元素，支持是否重复刪除, 否则只刪除第一次出现的元素
    /// - Parameters:
    ///   - elements: 被刪除的数组元素
    ///   - isRepeat: 是否刪除重复的元素
    @discardableResult
    mutating func wn_removeArray(_ elements: [Element], isRepeat: Bool = true) -> Array {
        for element in elements {
            if self.contains(element) {
                self.wn_remove(element, isRepeat: isRepeat)
            }
        }
        return self
    }
}

extension Array {
    /// 从数组中返回一个随机元素
    public var sample: Element? {
        //如果数组为空，则返回nil
        guard count > 0 else { return nil }
        let randomIndex = Int(arc4random_uniform(UInt32(count)))
        return self[randomIndex]
    }
     
    /// 从数组中从返回指定个数的元素
    ///
    /// - Parameters:
    ///   - size: 希望返回的元素个数
    ///   - noRepeat: 返回的元素是否不可以重复（默认为false，可以重复）
    public func sample(size: Int, noRepeat: Bool = true) -> [Element]? {
        //如果数组为空，则返回nil
        guard !isEmpty else { return nil }
         
        var sampleElements: [Element] = []
         
        //返回的元素可以重复的情况
        if !noRepeat {
            for _ in 0..<size {
                sampleElements.append(sample!)
            }
        }
        //返回的元素不可以重复的情况
        else{
            //先复制一个新数组
            var copy = self.map { $0 }
            for i in 0..<size {
                //当元素不能重复时，最多只能返回原数组个数的元素
                if copy.isEmpty { break }
                sampleElements.append(copy[i])
            }
        }
        
        return sampleElements
    }
}
